/*******************************************************************************
 *
 *    Copyright (c) Baina Info Tech Co. Ltd
 *
 *    
 *    StorageHelper
 *
 *    @author: dhu
 *    @since:  Jun 11, 2010
 *    @version: 1.0
 *
 ******************************************************************************/
package com.sdk.util.phone;

import java.io.File;
import java.lang.reflect.Method;


import android.os.Environment;
import android.os.StatFs;

/**
 * StorageHelper.
 * 
 * @author dhu
 * 
 */

// File externalStorageDir = StorageHelper.getExternalStorageDirectory();
// if
// (!Environment.MEDIA_MOUNTED.equals(StorageHelper.getExternalStorageState()))
// {
// code here��
// }
public class StorageHelper {

	private static final boolean HAS_PHONE_STARAGE;
	private static Method getPhoneStorageStateMethod;
	private static Method getPhoneStorageDirectoryMethod;
	static {
		boolean hasPhoneStorage = false;
		try {
			final Class<Environment> cls = Environment.class;
			getPhoneStorageDirectoryMethod = cls
					.getDeclaredMethod("getPhoneStorageDirectory");
			getPhoneStorageDirectoryMethod.setAccessible(true);

			getPhoneStorageStateMethod = cls
					.getDeclaredMethod("getPhoneStorageState");
			getPhoneStorageStateMethod.setAccessible(true);
			hasPhoneStorage = true;
		} catch (final Exception e) {
		}
		HAS_PHONE_STARAGE = hasPhoneStorage;
	}

	/**
	 * Gets the Android external storage directory.
	 */
	public static File getExternalStorageDirectory() {
		File dir = null;
		if (HAS_PHONE_STARAGE) {
			if (Environment.MEDIA_REMOVED
					.equals(getExternalStorageStateInternal())) {
				dir = getPhoneStorageDirectory();
			} else {
				dir = Environment.getExternalStorageDirectory();
			}
		} else {
			dir = Environment.getExternalStorageDirectory();
		}
		return dir;
	}

	public static boolean isSdCardAvaliable() {
		final String sdCurrentState = getExternalStorageState();
		if (sdCurrentState.equals(Environment.MEDIA_REMOVED)
				|| sdCurrentState.equals(Environment.MEDIA_UNMOUNTED)
				|| sdCurrentState.equals(Environment.MEDIA_UNMOUNTABLE)
				|| sdCurrentState.equals(Environment.MEDIA_NOFS)
				|| sdCurrentState.equals(Environment.MEDIA_BAD_REMOVAL)) {
			return false;
		} else {
			return true;
		}
	}

	public static boolean isSDCardAvailable() {
		if (!Environment.MEDIA_MOUNTED.equals(StorageHelper
				.getExternalStorageState())) {
			return false;
		}
		return true;
	}

	/**
	 * Gets the current state of the external storage device.
	 */
	public static String getExternalStorageState() {
		String state = Environment.MEDIA_REMOVED;
		if (HAS_PHONE_STARAGE) {
			if (Environment.MEDIA_REMOVED
					.equals(getExternalStorageStateInternal())) {
				state = getPhoneStorageStateInternal();
			} else {
				state = Environment.getExternalStorageState();
			}
		} else {
			state = Environment.getExternalStorageState();
		}
		return state;
	}

	private static String getExternalStorageStateInternal() {
		return Environment.getExternalStorageState();
	}

	private static String getPhoneStorageStateInternal() {
		try {
			if (HAS_PHONE_STARAGE) {
				return (String) getPhoneStorageStateMethod.invoke(null);
			}
		} catch (final Exception e) {
		}
		return Environment.MEDIA_REMOVED;
	}

	private static File getPhoneStorageDirectory() {
		try {
			if (HAS_PHONE_STARAGE) {
				return (File) getPhoneStorageDirectoryMethod.invoke(null);
			}
		} catch (final Exception e) {
		}
		return null;
	}

	/**
	 * 获取sdcard上面可用的存储空间大小
	 * 
	 * @return
	 */
	public static long getavailableStorageSize() {
		final StatFs statFs = new StatFs(StorageHelper
				.getExternalStorageDirectory().getPath());
		final long availableBlocks = statFs.getAvailableBlocks();
		return availableBlocks;
	}

	/**
	 * 获取整个sdcard的容量
	 * 
	 * @return
	 */
	public static long getWholeStorageSize() {
		final StatFs statFs = new StatFs(StorageHelper
				.getExternalStorageDirectory().getPath());
		final long blockSize = statFs.getBlockSize();
		final long totalBlocks = statFs.getBlockCount();
		return totalBlocks * blockSize;
	}
}
